package com.wangyadong.hobby.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;

public class PhaserDemo {
    static final Phaser phaser = new Phaser(1); // "1" (register self)

    public static void main(String[] args) throws InterruptedException {
        List<Runnable> tasks = new ArrayList<>();
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));

        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));
        tasks.add(() -> System.out.printf("%s running at %d%n",
                Thread.currentThread().getName(),
                System.currentTimeMillis()));


        runTasks(tasks);

        Thread.sleep(10000);
        int arrive = phaser.arrive();
        System.out.println("arrive thread is " + arrive);
    }

    static void runTasks(List<Runnable> tasks) {

// create and start threads
        for (final Runnable task : tasks) {
            int arrive = phaser.arrive();
            System.out.println(Thread.currentThread().getName() + " before register  arrive thread is " + arrive);
            phaser.register();
            System.out.println(Thread.currentThread().getName() + " after register  arrive thread is " + arrive);
            Runnable r = () ->
            {
//                try {
//                    Thread.sleep(50 + (int) (Math.random() * 300));
//                } catch (InterruptedException ie) {
//                    System.out.println("interrupted thread");
//                }
                phaser.arriveAndAwaitAdvance(); // await the ...
// creation of ...
// all tasks
                task.run();
            };
            Executors.newSingleThreadExecutor().execute(r);
        }
// allow threads to start and deregister self
        phaser.arriveAndDeregister();
    }
}